.pragma library

function init(colunas) {
    this.colunas = colunas;
    this.cartas = new Array();
    this.movimentosResolucao = new Array();
    this.movimentos = 0;

    this.reset = function() {
        for (var i = 1; i <= 15; i++)
            this.cartas[i-1] = i;
        this.cartas[this.cartas.length - 1] = 0;
    }

    this.newGame = function() {
        this.reset();
        for (var i = 0; i < 100; i++) {
            var jogada = this.jogadaAleatoria();
            this.mover(jogada[0]);
        }
        if (this.finalJogo())
            this.newGame();
        //console.log(cartas);
        this.movimentos = 0;
    }

    this.jogadaAleatoria = function() {
        var espacoBranco = this.posicaoNumero(0);
        //console.log("branquinhoooooooooooooooooooooooo");
        //console.log(espacoBranco);
        var linhas = espacoBranco[1][0] - 1;
        var x = espacoBranco[2][0];
        var y = espacoBranco[2][1];
        var primeiraLinha = x === 0;
        var ultimaLinha = x === linhas;
        console.log("xBranco:"+x+";yBranco:"+y+";linhas:"+linhas+";primeiraL:"+primeiraLinha+";ultimaL:"+ultimaLinha);
        var xFinal = 0;
        var yFinal = 0;
        var rand = Math.random();
        console.log("Número random: " + rand);
        if (y === this.colunas - 1) { //última coluna
            if (ultimaLinha) { //última linha: só dá pra mover o branco pra esquerda ou pra cima
                rand = Math.round(rand * 1);
                switch(rand) {
                case 0: {
                    xFinal = x - 1;
                    yFinal = y;
                    console.log("Aqui 10");
                }
                break;
                case 1: {
                    xFinal = x;
                    yFinal = y - 1;
                    console.log("Aqui 20");
                }
                break;
                }
            } else if (primeiraLinha) { //primeira linha: só dá pra mover o branco pra esquerda ou pra baixo
                rand = Math.round(rand * 1);
                switch(rand) {
                case 0: {
                    xFinal = x + 1;
                    yFinal = y;
                    console.log("Aqui 30");
                }
                break;
                case 1: {
                    xFinal = x;
                    yFinal = y - 1;
                    console.log("Aqui 40");
                }
                break;
                }
            } else { //dá pra mover o branco pra esquerda, cima ou baixo
                rand = Math.round(rand * 2);
                switch(rand) {
                case 0: {
                    xFinal = x + 1;
                    yFinal = y;
                    console.log("Aqui 50");
                }
                break;
                case 1: {
                    xFinal = x - 1;
                    yFinal = y;
                    console.log("Aqui 60");
                }
                break;
                case 2: {
                    xFinal = x;
                    yFinal = y - 1
                    console.log("Aqui 70");
                }
                break;
                }
            }
        } else if (y === 0) { //primeira coluna
            if (ultimaLinha) { //última linha: só dá pra mover o branco pra direira ou pra cima
                rand = Math.round(rand * 1);
                switch(rand) {
                case 0: {
                    xFinal = x - 1;
                    yFinal = y;
                    console.log("Aqui 80");
                }
                break;
                case 1: {
                    xFinal = x;
                    yFinal = y + 1;
                    console.log("Aqui 90");
                }
                break;
                }
            } else if (primeiraLinha) { //primeira linha: só dá pra mover o branco pra direira ou pra baixo
                rand = Math.round(rand * 1);
                switch(rand) {
                case 0: {
                    xFinal = x + 1;
                    yFinal = y;
                    console.log("Aqui 100");
                }
                case 1: {
                    xFinal = x;
                    yFinal = y + 1;
                    console.log("Aqui 200");
                }
                break;
                }
            } else { //dá pra mover o branco pra direira, cima ou baixo
                rand = Math.round(rand * 2);
                switch(rand) {
                case 0: {
                    xFinal = x + 1;
                    yFinal = y;
                    console.log("Aqui 300");
                }
                break;
                case 1: {
                    xFinal = x - 1;
                    yFinal = y;
                    console.log("Aqui 400");
                }
                break;
                case 2: {
                    xFinal = x;
                    yFinal = y + 1;
                    console.log("Aqui 500");
                }
                break;
                }
            }
        } else { //o branco pode ser movido para esquera ou direira
            if (ultimaLinha) { //última linha: só dá pra mover o branco pra esquerda, cima ou direira
                rand = Math.round(rand * 2);
                switch(rand) {
                case 0: {
                    xFinal = x - 1;
                    yFinal = y;
                    console.log("Aqui 600");
                }
                break;
                case 1: {
                    xFinal = x;
                    yFinal = y - 1;
                    console.log("Aqui 700");
                }
                break;
                case 2: {
                    xFinal = x;
                    yFinal = y + 1;
                    console.log("Aqui 800");
                }
                break;
                }
            } else if (primeiraLinha) { //primeira linha: só dá pra mover o branco pra esquerda, baixo ou direira
                rand = Math.round(rand * 2);
                switch(rand) {
                case 0: {
                    xFinal = x + 1;
                    yFinal = y;
                    console.log("Aqui 900");
                }
                break;
                case 1: {
                    xFinal = x;
                    yFinal = y - 1;
                    console.log("Aqui 1000");
                }
                break;
                case 2: {
                    xFinal = x;
                    yFinal = y + 1;
                    console.log("Aqui 2000");
                }
                break;
                }
            } else { //branco pode ser movido em qualquer direção
                rand = Math.round(rand * 3);
                switch(rand) {
                case 0: {
                    xFinal = x - 1;
                    yFinal = y;
                    console.log("Aqui 1");
                }
                break;
                case 1: {
                    xFinal = x + 1;
                    yFinal = y;
                    console.log("Aqui 2");
                }
                break;
                case 2: {
                    xFinal = x;
                    yFinal = y - 1;
                    console.log("Aqui 3");
                }
                break;
                case 3: {
                    xFinal = x;
                    yFinal = y + 1;
                    console.log("Aqui 4");
                }
                break;
                }
            }
        }
        //mover as cartas
        //var posicaoCartaBranco = numeroPosicao(colunas, x, y);
        var posicaoCartaNumero = this.numeroPosicao(xFinal, yFinal);
        //cartas[posicaoCartaBranco] = cartas[posicaoCartaNumero];
        //cartas[posicaoCartaNumero] = 0;
        var ret = [];
        ret[0] = this.cartas[posicaoCartaNumero]; //número atual
        ret[1] = [];
        ret[1][0] = x;
        ret[1][1] = y;
        ret[2] = [];
        ret[2][0] = xFinal;
        ret[2][1] = yFinal;
        console.log("=======");
        console.log(ret);
        return ret;
        /*if (lastNumberMovemented == cartas[posicaoCartaNumero]) {
            console.log("Mesmo número... rejogando...");
            return jogadaAleatoria(colunas);
        } else {
            lastNumberMovemented = cartas[posicaoCartaNumero];
            return ret;
        }*/
    }

    this.finalJogo = function() {
        if (this.cartas[this.cartas.length - 1] !== 0)
            return false;
        for (var i = 0; i < this.cartas.length - 1; i++)
            if (i == this.cartas.length - 2) {
                console.log("opaaaa!");
                return true;
            } else if (this.cartas[i] !== this.cartas[i + 1] - 1) {
                console.log("ihhhhhhhh!");
                return false;
            }
        return true;
    }

    this.mover = function(numero) {
        var positionsNumero = this.posicaoNumero(numero);
        var positionsNumeroBranco = this.posicaoNumero(0);
        var colunaAdjacente = positionsNumero[2][1] + 1 == positionsNumeroBranco[2][1] ||
            positionsNumero[2][1] - 1 == positionsNumeroBranco[2][1];
        var linhaAdjacente = positionsNumero[2][0] + 1 == positionsNumeroBranco[2][0] ||
            positionsNumero[2][0] - 1 == positionsNumeroBranco[2][0] || positionsNumero[2][0] == positionsNumeroBranco[2][0];

        var pode = ((!colunaAdjacente && linhaAdjacente && (positionsNumero[2][1] == positionsNumeroBranco[2][1])) ||
                    (colunaAdjacente && positionsNumero[2][0] == positionsNumeroBranco[2][0]));
        var ret = [];
        ret[0] = pode;
        if (pode) {
            this.cartas[positionsNumeroBranco[0]] = this.cartas[positionsNumero[0]];
            this.cartas[positionsNumero[0]] = 0;
            this.movimentos++;
            ret[1] = positionsNumero;
            ret[2] = positionsNumeroBranco;
        }
        return ret;
    }

    this.numeroPosicao = function(x, y) {
        var posicao = (x + 1) * this.colunas - (this.colunas - y + 1) + 1;
        console.log("Calcular: colunas:" + this.colunas + ";x:" + x + ";y:"+y + ";número calculado:" + posicao);
        return posicao;
    }

    this.posicaoNumero = function(numero) {
        var ret = [];
        var pos = -1;
        for (var i = 0; i < this.cartas.length; i++) {
            if (this.cartas[i] == numero) {
                pos = i;
                break;
            }
        }
        if (pos >= 0) {
            var linhas = this.cartas.length / this.colunas;
            var posicaoColuna = (pos < this.colunas ? pos : pos % this.colunas);
            var posicaoLinha = Math.floor(pos / this.colunas);
            //console.log("Está na posicao: " + posicaoLinha + " x " + posicaoColuna);
            ret[0] = pos
            ret[1] = [];
            ret[2] = [];
            ret[1][0] = linhas;
            ret[1][1] = this.colunas;
            ret[2][0] = posicaoLinha;
            ret[2][1] = posicaoColuna;
            return ret
        }
        return ret;
    }

    this.iniciarCartas = function() {
        for (var i = 1; i <= 15; i++)
            this.cartas.push(i);
        this.cartas.push(0);
        console.log("Logadooooooooooooooooooooo!!!!!!");
    }
    console.log("Criar as cartas!!!!!!!!!!!!!!!!!!!!!!!!");
    this.iniciarCartas();
}

var instancias = [,];

function createObject(key, colunas) {
    if (!(key in instancias)) {
        console.log("hash " + key + " novo: criando objeto.");
        instancias[key] = new init(colunas);
        return instancias[key];
    } else {
        console.log("hash "+ key +" já existe: retornando objeto.");
        return instancias[key];
    }
}

function deleteObject(key) {
    instancias[key] = null;
}
